package main

import (
	"bufio"
	"fmt"
	"strings"
	"unicode"
	"bytes"
)

func main()  {
	// 字符串操作
	//stringsMain()
	// 字符串进行替换
	//stringsReplaceMain()
	//// 读取数据
	//stringsReaderMain()

	// 最大限度地减少了内存复制,高效地构建字符串
	stringsBuilderMain()
}

// 字符串操作
func stringsMain()  {
	aaa := "hello"
	bbb := "world"
	fmt.Println(bbb)

	// 字符出克隆，返回字符串的副本
	stringsClone := strings.Clone(aaa)
	fmt.Println(stringsClone)

	// 按字典顺序比较两个字符串的整数
	// 如果a==b，结果将为0，如果a<b，结果将为-1，如果a>b，结果将为+1。
	stringsCompare := strings.Compare(aaa,bbb)
	fmt.Println(stringsCompare)

	// 统计 substr 在 s 中的数据量，若 substr 是 空，则返回 s 的长度
	stringsCount := strings.Count(aaa,"")
	fmt.Println(stringsCount)

	// substr 是否在 s 中
	stringsContains := strings.Contains(aaa,"w")
	fmt.Println(stringsContains)

	// chars 中的任何字符是否在 s 中
	stringsContainsAny := strings.ContainsAny(aaa,"we")
	fmt.Println(stringsContainsAny)

	// 单个字符 r 是否在 s 内
	stringsContainsRune := strings.ContainsRune(aaa,'h')
	fmt.Println(stringsContainsRune)

	// 检索b在a中第一次出现的位置，未检索到返回-1
	stringsIndex := strings.Index(aaa, "l")
	fmt.Println(stringsIndex)

	// 返回s中c的第一个实例的索引,不存在则返回 -1
	stringsIndexByte := strings.IndexByte(aaa,byte('l'))
	fmt.Println(stringsIndexByte)

	// 返回s中r的第一个实例的索引,不存在则返回 -1
	stringsIndexRune := strings.IndexRune(aaa,'o')
	fmt.Println(stringsIndexRune)

	// 检索 chars 中任意字符 在 s 中首个出现的位置，未检索到返回 -1
	stringsIndexAny := strings.IndexAny(aaa,"oe")
	fmt.Println(stringsIndexAny)

	// 检测 s 中最后一个 substr 位置,如果不存在，则返回 -1
	stringsLastIndex := strings.LastIndex(aaa,"l")
	fmt.Println(stringsLastIndex)

	// 检索 chars 中任意字符 在 s 中最后一个出现的位置，未检索到返回 -1
	stringsLastIndexAny := strings.LastIndexAny(aaa,"oe")
	fmt.Println(stringsLastIndexAny)

	// 返回s中c的最后一个实例的索引,不存在则返回 -1
	stringsLastIndexByte := strings.LastIndexByte(aaa,byte('l'))
	fmt.Println(stringsLastIndexByte)

	// 将 s 以指定字符 sep 分隔成string数组
	stringsSplit := strings.Split(aaa,"e")
	fmt.Println(stringsSplit)

	// // 将 s 以指定字符 sep 分隔成string数组,保留 sep
	stringsSplitAfter := strings.SplitAfter(aaa,"e")
	fmt.Println(stringsSplitAfter)

	// 将s以指定字符 sep 分割成string数组，保留 sep。n为分割个数，-1分割所有
	stringsSplitAfterN := strings.SplitAfterN(aaa,"l",4)
	fmt.Println(stringsSplitAfterN)

	// 将 s 以指定字符 sep 分隔成string数组，n为分隔个数，-1 为分隔所有
	stringsSplitN := strings.SplitN(aaa,"l",5)
	fmt.Println(stringsSplitN)

	// 以一个或者多个空格分割成切片
	stringsFields := strings.Fields("hello world, hello key!")
	fmt.Println(stringsFields)

	// 根据指定方法分割成切片
	stringsFieldsFunc := strings.FieldsFunc("  foo1;bar2,baz3...", func(c rune) bool {
		return !unicode.IsLetter(c) && !unicode.IsNumber(c) // 以 不是字符或者数字 进行分割
	})
	fmt.Println(stringsFieldsFunc)

	// 将string数组以指定字符连接成一个新的string
	stringsJoin := strings.Join([]string{aaa,bbb}," != ")
	fmt.Println(stringsJoin)

	// 字符串 s 是否以 prefix 前缀开头。
	stringsHasPrefix := strings.HasPrefix(aaa,"he")
	fmt.Println(stringsHasPrefix)

	// 字符串 s 是否以 suffix 后缀结尾
	stringsHasSuffix := strings.HasSuffix(aaa,"lo")
	fmt.Println(stringsHasSuffix)

	// 遍历a按指定的rune方法处理每个字符
	stringsMap := strings.Map(func(r rune) rune {
		if r >= 'A' && r <= 'Z' {

			return r

		} else {

			return 'a'

		}
	}, aaa)
	fmt.Println(stringsMap)

	// 返回 count 个 s 连接起来的字符串
	stringsRepeat := strings.Repeat(aaa,3)
	fmt.Println(stringsRepeat)

	// 将 s 中所有的字符都大写
	stringsToUpper := strings.ToUpper(aaa)
	fmt.Println(stringsToUpper)

	// 将 s 中所有的字符都小写
	stringsToLower := strings.ToLower("HELLO")
	fmt.Println(stringsToLower)

	// 返回一个 所有字母大写 的标题格式
	stringsToTitle := strings.ToTitle(aaa)
	fmt.Println(stringsToTitle)

	// 使用指定的映射表将 s 中的所有字符修改为大写格式返回。
	stringsToUpperSepcial := strings.ToUpperSpecial(unicode.SpecialCase{}, aaa)
	fmt.Println(stringsToUpperSepcial)

	// 使用指定的映射表将 s 中的所有字符修改为小写格式返回。
	stringsToLowerSpecial := strings.ToLowerSpecial(unicode.SpecialCase{}, "HELLO")
	fmt.Println(stringsToLowerSpecial)

	// 用指定的映射表将 s 中的所有字符修改为标题格式返回。
	stringsToTitleSpecial := strings.ToTitleSpecial(unicode.SpecialCase{},"")
	fmt.Println(stringsToTitleSpecial)

	// 运行无效的UTF-8字节序列,替换为 replacement 字符串，该字符串可能为空。
	stringsToValidUTF8 := strings.ToValidUTF8(aaa,"a")
	fmt.Println(stringsToValidUTF8)

	// s 首字母大写
	stringsTitle := strings.Title(aaa)
	fmt.Println(stringsTitle)

	// 去除开头结尾所有的 指定字符串中的任意字符
	stringsTrim := strings.Trim("  aaa234bbb   ", " ")
	fmt.Println(stringsTrim)

	// 去除开头所有的 指定字符串中的任意字符
	stringsTrimLeft := strings.TrimLeft("  1aaa234bbb1   ", "0123456789")
	fmt.Println(stringsTrimLeft)

	// 去除结尾所有的 指定字符串中的任意字符
	stringsTrimRight := strings.TrimRight("  1aaa234bbb1   ", "1234567890")
	fmt.Println(stringsTrimRight)

	// 按自定义方法 去除开头结尾所有指定内容
	stringsTrimFunc := strings.TrimFunc("aaa123bbb", unicode.IsLetter)
	fmt.Println(stringsTrimFunc)

	// 按自定义方法 去除开头所有指定内容
	stringsTrimLeftFunc := strings.TrimLeftFunc("aAaAaAaasd123sdf", unicode.IsLetter)
	fmt.Println(stringsTrimLeftFunc)

	// 按自定义方法 去除结尾所有指定内容
	stringsTrimRightfunc := strings.TrimRightFunc("aaaa123sdfsd", unicode.IsLetter)
	fmt.Println(stringsTrimRightfunc)

	// 去除开头结尾所有的 空格换行回车缩进
	stringsTrimSpace := strings.TrimSpace("  lsdjf23kdjf ")
	fmt.Println(stringsTrimSpace)

	// 如果a以b开头，则返回a去掉b开头部分的新string。如果不是，返回a
	stringsTrimPrefix := strings.TrimPrefix(aaa,"he")
	fmt.Println(stringsTrimPrefix)

	// 如果a以b结尾，则返回a去掉b结尾部分的新string。如果不是，返回a
	stringsTrimSuffix := strings.TrimSuffix(aaa,"he")
	fmt.Println(stringsTrimSuffix)

	// 自定义方法检索首个字符的位置，未检索到返回-1
	stringsIndexFunc := strings.IndexFunc("Hello, 世界", func(c rune) bool {
		return unicode.Is(unicode.Han, c) // 是否包含中文字符
	})
	println(stringsIndexFunc)

	// 自定义方法检索最后一个字符的位置，未检索到返回-1
	stringsLastIndexFunc := strings.LastIndexFunc("Hello, 世界", func(c rune) bool {
		return unicode.Is(unicode.Han, c) // 是否包含中文字符
	})
	println(stringsLastIndexFunc)

	// 返回一个 将a中的b替换为c 的新string，n为替换个数，-1替换所有
	stringsReplace := strings.Replace(aaa, "e", "h", -1)
	fmt.Println(stringsReplace)

	// 返回一个 将a中的b替换为c 的新string
	stringsReplaceAll := strings.ReplaceAll("sldjfsldfjksdfl", "l", "d")
	fmt.Println(stringsReplaceAll)

	// 判断a与b是否相同(将unicode大写、小写、标题三种格式字符视为相同)
	stringsEqualFold := strings.EqualFold("hello", "HellO")
	fmt.Println(stringsEqualFold)

	// 在 s 中按 sep 进行剪切，返回 sep 前后字符串，还有是否 sep 存在 s 中
	stringsCutBefore,stringsCutAfter,StringsCutBool := strings.Cut(aaa,"e")
	fmt.Println(stringsCutBefore,stringsCutAfter,StringsCutBool)

}

// 字符串进行替换
func stringsReplaceMain()  {
	// 使用提供的多组old、new字符串对创建并返回一个*strings.Replacer
	// 替换是依次进行的，匹配时不会重叠
	r := strings.NewReplacer("<", "&lt;", ">", "&gt;")
	// 进行字符串替换
	stringsReplace := r.Replace("This is <b>HTML</b>!")
	fmt.Println(stringsReplace)

	// w中写入s的所有替换
	var buf bytes.Buffer
	stringsWriteString,_ := r.WriteString(&buf,"This is <b>HTML</b>!")
	fmt.Println(stringsWriteString)
}

// 读取数据
func stringsReaderMain()  {
	// 创建一个从s读取数据的Reader
	stringsReader := strings.NewReader("hello , world")

	// 返回字符串未读部分的字节数。
	stringsReaderLen := stringsReader.Len()
	fmt.Println(stringsReaderLen)

	// 返回基础字符串的原始长度。
	stringsReaderSize := stringsReader.Size()
	fmt.Println(stringsReaderSize)

	// 读取数据到 b 中，长度为 b 的容量, 实现 io.reader 接口
	stringsReaderRead,_ := stringsReader.Read(make([]byte,5))
	fmt.Println(stringsReaderRead)

	// 读取偏移量为 off 的数据到 b 中, 实现 io.readerAt 接口
	stringsReaderReadAt,_ := stringsReader.ReadAt(make([]byte,5),5)
	fmt.Println(stringsReaderReadAt)

	// 读取一个字节数据, 实现 io.ByteReader 接口
	stringsReaderReadByte,_ := stringsReader.ReadByte()
	fmt.Println(string(stringsReaderReadByte))

	// 实现 io.ByteScanner 接口
	stringsReader.UnreadByte()

	// 实现 io.RuneReader 接口
	stringsReader.ReadRune()

	// 实现 io.RuneScanner 接口
	stringsReader.UnreadRune()

	// 实现 io.Seeker 接口
	stringsReader.Seek(5,5)

	// 实现 io.WriterTo 接口
	var buf bufio.Writer
	stringsReader.WriteTo(&buf)

	// 重置从s读取的读卡器。
	stringsReader.Reset("hello")

}

func stringsBuilderMain()  {
	var builder strings.Builder

	// 将s的内容附加到b的缓冲区。
	stringsBuilderWriteStringInt,_ := builder.WriteString("hello , world")
	fmt.Println(stringsBuilderWriteStringInt)

	// 返回累计的字符串
	stringsBuilderString := builder.String()
	fmt.Println(stringsBuilderString)

	// 返回累计字节数
	stringsBuilderLen := builder.Len()
	fmt.Println(stringsBuilderLen)

	// 返回构建器底层字节片的容量。它是为正在生成的字符串分配的总空间，包括任何已经写入的字节。
	stringsBuilderCap := builder.Cap()
	fmt.Println(stringsBuilderCap)

	// 增加b的容量，再增加n字节的空间
	builder.Grow(10)

	// 将p的内容附加到b的缓冲区。 总是返回len（p）
	stringsBuilderWrite,_ := builder.Write([]byte("hello"))
	fmt.Println(stringsBuilderWrite)

	// 将字节c追加到b的缓冲区
	builder.WriteByte('a')

	// 将Unicode代码点r的UTF-8编码附加到b的缓冲区
	stringsBuilderWriteRune,_ := builder.WriteRune('1')
	fmt.Println(stringsBuilderWriteRune)

	// 重置将生成器重置为空。
	builder.Reset()

}


